"""
数据模型定义 - 扩展功能模块
"""
from pydantic import BaseModel, Field, validator
from typing import List, Optional, Dict, Any, Union
from datetime import datetime
from decimal import Decimal
from enum import Enum


class UserRole(str, Enum):
    ADMIN = "admin"
    MEMBER = "member"
    GUEST = "guest"
    MAINTAINER = "maintainer"


class TaskStatus(str, Enum):
    PENDING = "pending"
    IN_PROGRESS = "in_progress"
    COMPLETED = "completed"
    REJECTED = "rejected"
    CANCELLED = "cancelled"


class TaskPriority(str, Enum):
    LOW = "low"
    MEDIUM = "medium"
    HIGH = "high"
    URGENT = "urgent"


class DeviceStatus(str, Enum):
    ACTIVE = "active"
    INACTIVE = "inactive"
    MAINTENANCE = "maintenance"
    ERROR = "error"


class AnalysisType(str, Enum):
    SIGNAL_QUALITY = "signal_quality"
    ANOMALY_DETECTION = "anomaly_detection"
    PATTERN_RECOGNITION = "pattern_recognition"


class SeverityLevel(str, Enum):
    LOW = "low"
    MEDIUM = "medium"
    HIGH = "high"
    CRITICAL = "critical"


class ExportType(str, Enum):
    EXCEL = "excel"
    CSV = "csv"
    JSON = "json"


class ExportStatus(str, Enum):
    PROCESSING = "processing"
    COMPLETED = "completed"
    FAILED = "failed"


# 用户相关模型
class UserIn(BaseModel):
    username: str = Field(..., min_length=3, max_length=100)
    email: str = Field(..., regex=r'^[^@]+@[^@]+\.[^@]+$')
    password: str = Field(..., min_length=6)
    full_name: Optional[str] = Field(None, max_length=100)
    role: UserRole = UserRole.MEMBER
    team_id: Optional[str] = None


class UserOut(BaseModel):
    user_id: str
    username: str
    email: str
    full_name: Optional[str]
    role: UserRole
    team_id: Optional[str]
    is_active: bool
    last_login: Optional[datetime]
    created_at: datetime
    updated_at: datetime

    class Config:
        orm_mode = True


class UserLogin(BaseModel):
    username: str
    password: str


# 团队相关模型
class TeamIn(BaseModel):
    team_name: str = Field(..., min_length=1, max_length=100)
    description: Optional[str] = Field(None, max_length=500)


class TeamOut(BaseModel):
    team_id: str
    team_name: str
    description: Optional[str]
    owner_id: str
    is_active: bool
    created_at: datetime
    updated_at: datetime

    class Config:
        orm_mode = True


# 设备相关模型 (扩展)
class DeviceIn(BaseModel):
    device_id: str
    device_name: Optional[str] = Field(None, max_length=100)
    device_model: Optional[str] = Field(None, max_length=100)
    team_id: Optional[str] = None
    os_version: Optional[str] = Field(None, max_length=50)
    app_version: Optional[str] = Field(None, max_length=50)
    firmware_version: Optional[str] = Field(None, max_length=50)
    hardware_version: Optional[str] = Field(None, max_length=50)


class DeviceOut(BaseModel):
    device_id: str
    device_name: Optional[str]
    device_model: Optional[str]
    team_id: Optional[str]
    owner_id: Optional[str]
    os_version: Optional[str]
    app_version: Optional[str]
    firmware_version: Optional[str]
    hardware_version: Optional[str]
    status: DeviceStatus
    last_seen: Optional[datetime]
    battery_level: Optional[int] = Field(None, ge=0, le=100)
    temperature: Optional[float]
    storage_usage: Optional[float] = Field(None, ge=0, le=100)
    cpu_usage: Optional[float] = Field(None, ge=0, le=100)
    memory_usage: Optional[float] = Field(None, ge=0, le=100)
    location_latitude: Optional[Decimal]
    location_longitude: Optional[Decimal]
    location_accuracy: Optional[float]
    is_active: bool
    created_at: datetime
    updated_at: datetime

    class Config:
        orm_mode = True


class DeviceStatusUpdate(BaseModel):
    device_id: str
    status: DeviceStatus
    battery_level: Optional[int] = Field(None, ge=0, le=100)
    temperature: Optional[float]
    storage_usage: Optional[float] = Field(None, ge=0, le=100)
    cpu_usage: Optional[float] = Field(None, ge=0, le=100)
    memory_usage: Optional[float] = Field(None, ge=0, le=100)
    location_latitude: Optional[Decimal]
    location_longitude: Optional[Decimal]
    location_accuracy: Optional[float]


# 任务相关模型
class TaskIn(BaseModel):
    title: str = Field(..., min_length=1, max_length=200)
    description: Optional[str] = Field(None, max_length=1000)
    assignee_id: Optional[str] = None
    team_id: str
    priority: TaskPriority = TaskPriority.MEDIUM
    due_date: Optional[datetime] = None
    related_record_id: Optional[str] = None
    related_device_id: Optional[str] = None
    tags: Optional[List[str]] = Field(default_factory=list)
    attachments: Optional[List[str]] = Field(default_factory=list)


class TaskOut(BaseModel):
    task_id: str
    title: str
    description: Optional[str]
    assignee_id: Optional[str]
    creator_id: str
    team_id: str
    status: TaskStatus
    priority: TaskPriority
    due_date: Optional[datetime]
    related_record_id: Optional[str]
    related_device_id: Optional[str]
    tags: Optional[List[str]]
    attachments: Optional[List[str]]
    created_at: datetime
    updated_at: datetime
    completed_at: Optional[datetime]

    class Config:
        orm_mode = True


class TaskUpdate(BaseModel):
    title: Optional[str] = Field(None, min_length=1, max_length=200)
    description: Optional[str] = Field(None, max_length=1000)
    assignee_id: Optional[str] = None
    status: Optional[TaskStatus] = None
    priority: Optional[TaskPriority] = None
    due_date: Optional[datetime] = None
    tags: Optional[List[str]] = None
    attachments: Optional[List[str]] = None


class TaskCommentIn(BaseModel):
    task_id: str
    content: str = Field(..., min_length=1, max_length=1000)
    parent_comment_id: Optional[str] = None


class TaskCommentOut(BaseModel):
    comment_id: str
    task_id: str
    user_id: str
    content: str
    parent_comment_id: Optional[str]
    created_at: datetime
    updated_at: datetime

    class Config:
        orm_mode = True


# AI分析相关模型
class AIAnalysisIn(BaseModel):
    record_id: str
    device_id: str
    analysis_type: AnalysisType
    signal_data: List[Dict[str, Any]]  # 原始信号数据


class AIAnalysisOut(BaseModel):
    analysis_id: str
    record_id: str
    device_id: str
    analysis_type: AnalysisType
    result_label: Optional[str]
    confidence_score: float = Field(..., ge=0, le=1)
    severity_level: Optional[SeverityLevel]
    details: Optional[Dict[str, Any]]
    model_version: Optional[str]
    processing_time_ms: Optional[int]
    created_at: datetime

    class Config:
        orm_mode = True


# 热力图相关模型
class HeatmapDataIn(BaseModel):
    record_id: str
    device_id: str
    data_type: str = Field(..., description="signal_strength, frequency, time_frequency")
    width: int = Field(..., gt=0)
    height: int = Field(..., gt=0)
    data_points: List[List[float]]
    color_scheme: str = Field(default="viridis", description="viridis, jet, gray, hot")


class HeatmapDataOut(BaseModel):
    heatmap_id: str
    record_id: str
    device_id: str
    data_type: str
    width: int
    height: int
    data_points: List[List[float]]
    min_value: Optional[float]
    max_value: Optional[float]
    color_scheme: str
    created_at: datetime

    class Config:
        orm_mode = True


# 趋势图相关模型
class TrendDataIn(BaseModel):
    record_id: str
    device_id: str
    metric_name: str = Field(..., description="signal_strength, rsrp, rsrq, snr")
    time_series: List[Dict[str, Union[float, datetime]]]
    aggregation_type: str = Field(default="raw", description="raw, minute, hour, day")


class TrendDataOut(BaseModel):
    trend_id: str
    record_id: str
    device_id: str
    metric_name: str
    time_series: List[Dict[str, Union[float, datetime]]]
    aggregation_type: str
    created_at: datetime

    class Config:
        orm_mode = True


# 导出相关模型
class ExportRequest(BaseModel):
    export_type: ExportType
    filter_criteria: Dict[str, Any] = Field(default_factory=dict)
    file_format: str = Field(default="xlsx", description="xlsx, csv, json")
    include_attachments: bool = Field(default=False)


class ExportRecordOut(BaseModel):
    export_id: str
    user_id: str
    team_id: str
    export_type: ExportType
    file_name: str
    file_path: str
    file_size: Optional[int]
    filter_criteria: Optional[Dict[str, Any]]
    record_count: Optional[int]
    checksum: Optional[str]
    status: ExportStatus
    created_at: datetime
    completed_at: Optional[datetime]
    expires_at: Optional[datetime]

    class Config:
        orm_mode = True


# 系统配置相关模型
class SystemConfigIn(BaseModel):
    config_key: str = Field(..., min_length=1, max_length=100)
    config_value: str = Field(..., max_length=2000)
    config_type: str = Field(default="string", description="string, number, boolean, json")
    description: Optional[str] = Field(None, max_length=500)
    is_system: bool = Field(default=False)


class SystemConfigOut(BaseModel):
    config_id: str
    config_key: str
    config_value: str
    config_type: str
    description: Optional[str]
    is_system: bool
    created_at: datetime
    updated_at: datetime

    class Config:
        orm_mode = True


# 审计日志相关模型
class AuditLogOut(BaseModel):
    log_id: str
    user_id: Optional[str]
    action: str
    resource_type: Optional[str]
    resource_id: Optional[str]
    details: Optional[Dict[str, Any]]
    ip_address: Optional[str]
    user_agent: Optional[str]
    created_at: datetime

    class Config:
        orm_mode = True


# 响应模型
class PaginatedResponse(BaseModel):
    items: List[Any]
    total: int
    page: int
    page_size: int
    total_pages: int


class APIResponse(BaseModel):
    success: bool
    message: str
    data: Optional[Any] = None
    error_code: Optional[str] = None


# 统计相关模型
class DashboardStats(BaseModel):
    total_devices: int
    active_devices: int
    total_tasks: int
    pending_tasks: int
    completed_tasks: int
    total_exports: int
    total_users: int
    team_count: int


class DeviceStats(BaseModel):
    device_id: str
    device_name: str
    total_records: int
    avg_signal_strength: float
    last_analysis: Optional[datetime]
    ai_confidence_avg: Optional[float]
    anomaly_count: int
    status: DeviceStatus